home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / tcomm50.zip / QUICKB.C < prev    next >
Text File  |  1988-09-24  |  25KB  |  1,123 lines

  1. /*
  2. **  QUICKB.C - Quick B Protocol Support routines
  3. **
  4. **    converted to C by Paul M. Resch
  5. **  adapted to LiteComm(tm) ToolBox by Information Technology, Ltd.
  6. */
  7.  
  8. /*
  9. ** This module implements the B-Protocol Functions.
  10. **
  11. ** bp_DLE should be invoked whenever a <DLE> is received.
  12. ** bp_ENQ should be called whenever an <ENQ> is received.
  13. ** bp_ESC_I should be called when the sequence <ESC><I> is received.
  14. **
  15. ** This source was originally derived from QUICKB.INC, written by
  16. ** Russ Ranshaw, CompuServe Incorporated.
  17. **
  18. */
  19.  
  20. #include "litecomm.h"
  21. #include "litexm.h"
  22. #include <vcstdio.h>
  23.  
  24. #include <dos.h>
  25.  
  26. #ifdef M_I86
  27. #include <stdlib.h>
  28. #include <fcntl.h>
  29. #include <io.h>
  30. #include <sys\types.h>
  31. #include <sys\stat.h>
  32. #endif
  33.  
  34. #ifdef __TURBOC__
  35. #include <conio.h>
  36. #include <fcntl.h>
  37. #include <io.h>
  38. #include <stat.h>
  39. #endif
  40.  
  41. extern unsigned int port;                /* defined in TTL main */
  42.  
  43. #define    TRUE    1
  44. #define    FALSE    0
  45.  
  46. #undef DLE
  47. #undef NAK
  48.  
  49. #define    DLE        16
  50. #define    ETX        03
  51. #define    NAK        21
  52. #define    ENQ        05
  53. #define    CR        0x0D
  54. #define    LF        0x0A
  55. #define    MAX_BUF_SIZE    1032            /* Largest data block we can handle */
  56. #define    MAX_SA        2                    /* Maximum number of waiting packets */
  57.  
  58. #define    DEF_BUF_SIZE    511                /* Default data block */
  59. #define    DEF_WS        1                    /* I can send 2 packets ahead */
  60. #define    DEF_WR        1                    /* I can receive single send-ahead */
  61. #define    DEF_BS        8                    /* I can handle 1024 bytes */
  62. #define    DEF_CM        1                    /* I can handle CRC */
  63. #define    DEF_DQ        1                    /* I can handle non-quoted NUL */
  64.  
  65. #define    MAX_ERRORS    10
  66.  
  67. #define incr_seq(v)    (v == 9 ? 0 : v+1)    /* macro to incr seq number */
  68. #define incr_SA(v)  (v == MAX_SA ? 0 : v + 1 )
  69. #define    send_enq() (lc_put(port, ENQ))
  70.  
  71.  
  72. /*
  73. ** Receive States
  74. */
  75.  
  76. #define    R_GET_DLE        0
  77. #define    R_GET_B            1
  78. #define    R_GET_SEQ        2
  79. #define    R_GET_DATA        3
  80. #define    R_GET_CHECKSUM    4
  81. #define    R_SEND_ACK        5
  82. #define    R_TIMED_OUT        6
  83. #define    R_SUCCESS        7
  84.  
  85. /*
  86. ** Send States
  87. */
  88.  
  89. #define    S_GET_DLE    1
  90. #define    S_GET_NUM    2
  91. #define    S_HAVE_ACK    3
  92. #define    S_GET_PACKET    4
  93. #define    S_TIMED_OUT    5
  94. #define    S_SEND_NAK    6
  95. #define    S_SEND_ENQ    7
  96. #define    S_SEND_DATA    8
  97.  
  98. typedef    struct    PACKETB
  99. {
  100.     int        seq;                        /* Packet's sequence number */
  101.     int        num;                        /* Number of bytes in packet */
  102.     unsigned char buf[MAX_BUF_SIZE];     /* Actual packet data */
  103. } PACKET;
  104.  
  105. static    PACKET    SA_Buf[MAX_SA+1];          /* Send-ahead buffers */
  106.  
  107. /*
  108. ** Table of control characters that need to be masked
  109. */
  110.  
  111. static    char mask_table[] =
  112. {
  113.     0, 0, 0, 1, 0, 1, 0, 0,               /* NUL SOH SOB ETX EOT ENQ SYN BEL */
  114.     0, 0, 0, 0, 0, 0, 0, 0,                /* BS  HT  LF  VT  FF  CR  SO  SI  */
  115.     1, 1, 0, 1, 0, 1, 0, 0,                /* DLE DC1 DC2 DC3 DC4 NAK ^V  ^W  */
  116.     0, 0, 0, 0, 0, 0, 0, 0                /* CAN ^Y  ^Z  ESC ?   ?   ?   ?   */
  117. };
  118.  
  119. static    char    hex_digit[] = "0123456789ABCDEF";
  120.  
  121. static    int    seq_num;                    /* Current Sequence Number */
  122. static    int    lchecksm;                    /* May hold CRC */
  123. static    int    r_size;                        /* size of receiver buffer */
  124. static    unsigned int s_counter,
  125.                      r_counter;
  126. static    int    timed_out;                    /* we timed out before receiving */
  127. static    int    cchar;                        /* current character */
  128. static    int    masked;                        /* TRUE if ctrl character 'masked' */
  129. static    int    packet_received;            /* True if a packet was received */
  130. static    unsigned char r_buffer[MAX_BUF_SIZE];
  131.  
  132. /*
  133. ** Other End's Parameters
  134. */
  135.  
  136. static    char    His_WS;                    /* Sender's Window Send */
  137. static    char    His_WR;                    /* Sender's Window Receive */
  138. static    char    His_BS;                    /* Sender's Block Size */
  139. static    char    His_CM;                    /* Sender's Check Method */
  140.  
  141. /*
  142. ** Negotiated Parameters
  143. */
  144.  
  145. static    char    Our_WS;                    /* Negotiated Window Send */
  146. static    char    Our_WR;                    /* Negotiated Window Receive */
  147. static    char    Our_BS;                    /* Negotiated Block Size */
  148. static    char    Our_CM;                    /* Negotiated Check Method */
  149.  
  150. static    int    Quick_B;                    /* True if Quick B in effect */
  151. static    int    Use_CRC;                    /* True if CRC in effect */
  152. static    int    buffer_size;                /* Our_BS * 4 */
  153. static    int    SA_Max;                        /* 1 if SA not enabled, else MAX_SA */
  154. static    int    SA_Enabled;                    /* True if Send-Ahead is permitted  */
  155. static    int    ack_SA;                        /* Which SA_Buf is waiting for ACK */
  156. static    int    fill_SA;                    /* Which SA_Buf is ready, new data */
  157. static    int    SA_Waiting;                    /* Num of SA_Buf's waiting for ACK */
  158. static  int blkct;                      /* block counter for display */
  159. extern  char strbuf[];                  /* defined in qbttl */
  160.  
  161. static    void do_transport_parameters(void);
  162. static int    send_packet();
  163. static    int    SA_Flush();
  164.  
  165. /*
  166. ** crc
  167. **
  168. ** Calculates XMODEM-style CRC (uses the CCITT V.41 polynomial but
  169. ** completely backwards from the normal bit ordering).
  170. */
  171.  
  172.  
  173. static    unsigned    crc_table[] =
  174. {
  175.     0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
  176.     0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
  177.     0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
  178.     0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
  179.     0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
  180.     0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
  181.     0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
  182.     0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
  183.     0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
  184.     0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
  185.     0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
  186.     0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
  187.     0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
  188.     0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
  189.     0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
  190.     0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
  191.     0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
  192.     0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
  193.     0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
  194.     0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
  195.     0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
  196.     0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
  197.     0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
  198.     0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
  199.     0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
  200.     0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
  201.     0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
  202.     0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
  203.     0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
  204.     0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
  205.     0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
  206.     0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
  207. };
  208.  
  209. static    unsigned int    crc_16;
  210.  
  211. /*
  212. ** Upd_CRC updates crc_16 and returns the updated value.
  213. */
  214.  
  215. static    unsigned int    upd_CRC (value)
  216. unsigned int    value;
  217. {
  218.     crc_16 = crc_table [((crc_16 >> 8) ^ (value)) & 0xff] ^    (crc_16 << 8);
  219.     return( crc_16 );
  220. }
  221.  
  222. /*
  223. ** Update the checksum/CRC
  224. */
  225.  
  226. static    void    do_checksum(c)
  227. int    c;
  228. {
  229.     if (Quick_B && Use_CRC)
  230.         lchecksm = upd_CRC (c);
  231.     else
  232.     {
  233.         lchecksm = lchecksm << 1;
  234.  
  235.         if (lchecksm > 255)
  236.             lchecksm = (lchecksm & 0xFF) + 1;
  237.  
  238.         lchecksm = lchecksm + c;
  239.  
  240.         if (lchecksm > 255)
  241.             lchecksm = (lchecksm & 0xFF) + 1;
  242.     }
  243. }
  244.  
  245. static    void    send_failure( code )
  246. int    code;
  247. {
  248.     register PACKET    *p;
  249.  
  250.     ack_SA = 0;
  251.     fill_SA = 0;
  252.     SA_Waiting = 0;
  253.  
  254.     p = &SA_Buf [0];
  255.     p->buf[0] = 'F';
  256.     p->buf[1] = code;
  257.  
  258.     if ( send_packet (1))
  259.         SA_Flush();   /* Gotta wait for the host to ACK it */
  260. }
  261.  
  262. /*
  263. ** bp_ENQ is called when the terminal emulator receives the character <ENQ>
  264. ** from the host.  Its purpose is to initialize for B Protocol and tell the
  265. ** host that we support Quick B.
  266. */
  267.  
  268. void    bp_ENQ()
  269. {
  270.     seq_num = 0;
  271.     buffer_size = 511;               /* Set up defaults */
  272.     Quick_B     = FALSE;             /* Not Quick B Protocol */
  273.     Use_CRC     = FALSE;             /* Not CRC_16      */
  274.     SA_Enabled  = FALSE;             /* No Send-Ahead by us */
  275.     SA_Max